package ru.ipo.dces.plugins.admin.packetregistration.passwordgenerator;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Scanner;

/**
 * Created by IntelliJ IDEA.
 * User: ilya
 * Date: 13.06.11
 * Time: 13:20
 */
public class MarkovMatrix3D {

    private HashMap<String, Integer> matrix = new HashMap<String, Integer>();
    private HashMap<String, Integer> totalRow = new HashMap<String, Integer>();

    public MarkovMatrix3D(File... textFiles) throws IOException {
        for (File textFile : textFiles)
            processFile(textFile);

        evaluateRowsTotal();
    }

    public MarkovMatrix3D(HashMap<String, Integer> matrix) {
        this.matrix = matrix;
        evaluateRowsTotal();
    }

    private void incInMap(HashMap<String, Integer> map, String key) {
        incInMap(map, key, 1);
    }

    private void incInMap(HashMap<String, Integer> map, String key, int amount) {
        Integer v = map.get(key);
        if (v == null)
            v = 0;
        map.put(key, v + amount);
    }

    private String getFromIndexes(int... nums) {
        StringBuilder sb = new StringBuilder(nums.length * 2);
        for (int num : nums)
            sb.append((char)(num + 'a'));
        return sb.toString();
    }

    private void evaluateRowsTotal() {
        for (int i = -1; i < 26; i++)
            for (int j = -1; j < 26; j++)
                for (int k = 0; k < 26; k++)
                    incInMap(totalRow, getFromIndexes(i, j), getProbability(i, j, k));
    }

    private void processFile(File textFile) throws IOException {
        Scanner s = new Scanner(textFile);
        s.useDelimiter("[^A-Za-z]+");

        while (s.hasNext())
            processWord(s.next());

        s.close();
    }

    private void processWord(String word) {
        String prev = getFromIndexes(-1, -1);
        char[] chars = word.toLowerCase().toCharArray();
        for (char c : chars) {
            String key = prev + c;
            incInMap(matrix, key);
            prev = key.substring(1);
        }
    }

    public int getRowTotal(int c1, int c2) {
        Integer t = totalRow.get(getFromIndexes(c1, c2));
        return t == null ? 0 : t;
    }

    public int getProbability(int c1, int c2, int next) {
        Integer p = matrix.get(getFromIndexes(c1, c2, next));
        return p == null ? 0 : p;
    }

    public String serializeAsJavaArray(String mapName) {
        StringBuilder sb = new StringBuilder();

        for (String key : matrix.keySet())
            sb.append(mapName).append(".put(\"").append(key).append("\", ").append(matrix.get(key)).append(");\n");

        System.out.println(matrix.keySet().size());

        return sb.toString();
    }

}
